package com.codemart.lanze.modules.sys.service;

import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.codemart.lanze.common.annotation.DataFilter;
import com.codemart.lanze.modules.sys.mapper.RoleMapper;
import com.codemart.lanze.modules.sys.mapper.UserMapper;
import com.codemart.lanze.modules.sys.mapper.UserRoleMapper;
import com.codemart.lanze.modules.sys.model.Role;
import com.codemart.lanze.modules.sys.model.User;
import com.codemart.lanze.modules.sys.model.UserRole;
import com.xiaoleilu.hutool.crypto.SecureUtil;
import com.xiaoleilu.hutool.date.DateUtil;
import com.xiaoleilu.hutool.util.StrUtil;

/**
 * @description:
 * @author: lanze
 */
@Transactional
@Service
public class UserService extends ServiceImpl<UserMapper, User> {

	@Autowired
	private UserRoleMapper userRoleMapper;
	@Autowired
	private RoleMapper roleMapper;

	@DataFilter(tableAlias = "u")
	@Transactional(readOnly = true)
	public IPage<User> findPage(Integer pageNum, Integer pageSize, String username, String startTime, String endTime)
			throws Exception {

		QueryWrapper<User> queryWrapper = new QueryWrapper<>();

		if (StringUtils.isNotEmpty(username)) {
			queryWrapper.like("username", username);
		}
		if (StrUtil.isNotEmpty(startTime)) {
			queryWrapper.ge("createTime", DateUtil.beginOfDay(DateUtil.parse(startTime)));
		}
		if (StrUtil.isNotEmpty(endTime)) {
			queryWrapper.le("createTime", DateUtil.endOfDay(DateUtil.parse(endTime)));
		}

		IPage<User> iPage = this.page(new Page<>(pageNum, pageSize), queryWrapper);
		List<User> userList = iPage.getRecords();

		for (User user : userList) {
			Role role = roleMapper.findByUserId(user.getId());
			if (null != role) {
				user.setRoleName(role.getName());
			}
		}
		iPage.setRecords(userList);

		return iPage;
	}

	@Transactional(readOnly = true)
	public User findByUserName(String username) {
		QueryWrapper<User> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("username", username);
		return this.getOne(queryWrapper);
	}

	public Boolean saveUserAndUserRole(User user, Long roleId) throws Exception {
		int count = 0;
		// 加密
		user.setPassword(SecureUtil.md5().digestHex(user.getPassword()));
		user.setIsLock(false);
		user.setIsDel(false);
		Role role = roleMapper.selectById(roleId);
		if (Role.ROLE_TYPE.equalsIgnoreCase(role.getPerms())) {
			user.setIsAdmin(true);
		} else {
			user.setIsAdmin(false);
		}
		this.save(user);

		// 关联用户和角色信息
		UserRole userRole = new UserRole();
		userRole.setRoleId(roleId);
		userRole.setUserId(user.getId());
		// userRole.setCreateTime(user.getCreateTime());
		// userRole.setModifyTime(user.getCreateTime());
		count = userRoleMapper.insert(userRole);

		return count == 1;
	}

	@CacheEvict(value = "authenticationCache", key = "#user.username")
	public Boolean updateUserAndUserRole(User user, Long oldRoleId, Long roleId) throws Exception {
		int count = 0;
		// 加密
		user.setPassword(SecureUtil.md5().digestHex(user.getPassword()));
		if (!oldRoleId.equals(roleId)) {
			Role role = roleMapper.selectById(roleId);
			if (Role.ROLE_TYPE.equalsIgnoreCase(role.getPerms())) {
				user.setIsAdmin(true);
			} else {
				user.setIsAdmin(false);
			}
		}
		this.updateById(user);

		// 更新用户角色信息
		if (!oldRoleId.equals(roleId)) {

			QueryWrapper<UserRole> queryWrapper = new QueryWrapper<>();

			if (oldRoleId != null) {
				queryWrapper.like("role_id", oldRoleId);
			}
			if (user.getId() != null) {
				queryWrapper.like("user_id", user.getId());
			}

			UserRole ur = userRoleMapper.selectOne(queryWrapper);
			ur.setRoleId(roleId);
			// ur.setModifyTime(user.getModifyTime());
			count = userRoleMapper.updateById(ur);
		}
		return count == 1;
	}
}
